package de.khaled.diplom;

import java.text.DecimalFormat;
import java.util.Iterator;


public class Orlin {
	private TestDatenGenerator tdg = new TestDatenGenerator(10, 5, TestDatenGenerator.Bereiche.KauferBereich, TestDatenGenerator.Bereiche.NutzenBereich);
	private double delta = 0.0;
	private IdentifikationsGraph identifikations_graph = new IdentifikationsGraph();
	private RestNetzwerk restNetzwerk = new RestNetzwerk();
	DecimalFormat df = new DecimalFormat("#0.00");
	
	public Orlin(){
		
	}
	
	public double brechneMaxKapital(){
		double maxKapital = 0.0;
		for(Kaeufer kaeufer: tdg.kaeufer_liste){
			if(maxKapital < kaeufer.getKapital()){
				maxKapital = kaeufer.getKapital();
			}
		}
		return maxKapital;
	}
	
	public void berechneInitialisierungsPreis4Gut(){
		for(Kaeufer kaeufer: tdg.kaeufer_liste){
			double summeGutNutzenkaeufer = this.getSummeNutzenGut4Kaeufer(kaeufer);
			Iterator gueter = kaeufer.getNutzen().entrySet().iterator();			
			while(gueter.hasNext()){
				Gut gut = (Gut) gueter.next();
				// TODO round
				double temp = (kaeufer.getNutzen().get(gut)*kaeufer.getKapital())/((tdg.kaeufer_liste.size() + tdg.gut_liste.size())*summeGutNutzenkaeufer);
				kaeufer.getRhoProGut().put(gut, temp);
			}
		}
		
		for(Gut gut: tdg.gut_liste){
			double maxRho = 0.0;
			for(Kaeufer kaeufer: tdg.kaeufer_liste){
				if(maxRho < kaeufer.getRhoProGut().get(gut)){
					maxRho = kaeufer.getRhoProGut().get(gut);
				}
			}
			gut.setInitPreis(maxRho);
		}
	}
	
	public double getSummeNutzenGut4Kaeufer(Kaeufer kf){
		double ret = 0.0;
		Iterator it = kf.getNutzen().values().iterator();
		while(it.hasNext()){
			double npg = (double) it.next();
			ret += npg;
		}
		return ret;		
	}
	
	public void initialisierungsloesung(){
		this.delta = this.brechneMaxKapital()/(tdg.gut_liste.size()+tdg.kaeufer_liste.size());
		berechneInitialisierungsPreis4Gut();
		//berechne relative Nutzen
		for(Kaeufer kaeufer : this.tdg.kaeufer_liste){
			berechne_relative_nutzen_pro(kaeufer);
		}
	}
	
	public double round(double zahl) {
		return (double) ((int) zahl + (Math.round(Math.pow(10, 2)
				* (zahl - (int) zahl)))
				/ (Math.pow(10, 2)));

	}
	
	public void berechne_relative_nutzen_pro(Kaeufer kaeufer) {
		Iterator<Gut> it = kaeufer.getNutzen().keySet().iterator();
		while (it.hasNext()) {
			Gut gut = it.next();
			kaeufer.getRelativNutzen().put(
					gut,
					round(kaeufer.getNutzen().get(gut)
							/ gut.getInitPreis()));
		}
		kaeufer.berechneAlpha();
	}
	
	public void bauIdentifikationsGraph(){
		this.identifikations_graph.getKanten().clear();
		for (Kaeufer kaeufer : this.tdg.kaeufer_liste) {
			Iterator<Gut> it = kaeufer.getRelativNutzen().keySet().iterator();
			while (it.hasNext()) {
				Gut gut = it.next();
				double relative_nutzen = kaeufer.getRelativNutzen()
						.get(gut);
				if (df.format(relative_nutzen).equals(
						df.format(kaeufer.getAlpha()))) {
					Kante kante = new Kante(kaeufer, gut);
					this.identifikations_graph.getKanten().add(kante);
					gut.setVerbunden(true);
				}
			}
		}
		
	}
	
	public void berechneInitialisierungsVerteilung(){
		for(Kaeufer kaeufer : this.tdg.kaeufer_liste){
			for(Gut gut: this.identifikations_graph.getGueter4Kaeufer(kaeufer)){
					if(!gut.isAusverkauft() && kaeufer.getRestKapital() > 0){
					
						if(kaeufer.getRestKapital() >= gut.getRestPreis()){
							kaeufer.getVerteilung().put(gut, gut.getRestPreis());
							kaeufer.setRestKapital(kaeufer.getRestKapital() - gut.getRestPreis());
							gut.setRestPreis(0.0);
							gut.setAusverkauft(true);
						} else if(kaeufer.getRestKapital() < gut.getRestPreis()){							
							gut.setRestPreis(gut.getRestPreis() - kaeufer.getRestKapital());
							kaeufer.getVerteilung().put(gut, kaeufer.getRestKapital());
							kaeufer.setRestKapital(0.0);
						}
					}
			}
		}
	}
	
	public void bildeRestNetzwerk() {		
		this.restNetzwerk.getKanten().clear();
		for(Kante kante : this.identifikations_graph.getKanten()){
			Kante copy1 = new Kante(kante.getKaeuferKnoten(), kante.getGutKnoten());
			if(kante.getKaeuferKnoten().getVerteilung4Gut(kante.getGutKnoten()) >= 3*(this.tdg.kaeufer_liste.size() + this.tdg.gut_liste.size())*this.delta){
				Kante copy2 = new Kante(kante.getKaeuferKnoten(), kante.getGutKnoten());
				copy2.setDirection(-1);
				this.restNetzwerk.getKanten().add(copy2);
			} 
			copy1.setDirection(1);
			this.restNetzwerk.getKanten().add(copy1);
		}
	}
	
	public IdentifikationsGraph getIdentifikationsGraph() {
		return identifikations_graph;
	}

	public void setIdentifikationsGraph(IdentifikationsGraph identifikations_graph) {
		this.identifikations_graph = identifikations_graph;
	}
}
